package xxx.host.mpapi.advices;

import cn.hutool.core.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import xxx.common.enums.CodeEnum;
import xxx.common.exception.BizException;
import xxx.common.vo.Result;

import java.util.LinkedList;
import java.util.List;

/**
 * @author yuanchengman
 * @date 2021-02-24
 */
@RestControllerAdvice(basePackages = {"xxx.host.mpapi.controller"})
public class GlobalExceptionHandler {
    private static Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Object methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        LOGGER.error("ValidateErr", e);

        BindingResult result = e.getBindingResult();

        List<String> list = new LinkedList<>();
        result.getFieldErrors().forEach(error -> {
            String field = error.getField();
            Object value = error.getRejectedValue();
            String msg = error.getDefaultMessage();
            list.add(field + " " + msg);
        });

        // 然后提取错误提示信息进行返回
        Result bizResult = new Result(CodeEnum.SYSTEM_PARAM_ERROR.getCode(), StrUtil.join(",", list));
        return new Result<>(bizResult);
    }

    @ExceptionHandler(Throwable.class)
    public Object errorHandler(Throwable ex) {
        LOGGER.error(ex.getMessage(), ex);
        String errMsg = StrUtil.isNotEmpty(ex.getMessage()) ? ex.getMessage() : ex.toString();
        return new Result<>(CodeEnum.FAIL.getCode(), errMsg + ",stackTrace:" + getStackTrace(ex));
    }

    @ExceptionHandler(BizException.class)
    public Object errorHandler(BizException ex) {
        LOGGER.error(ex.getMessage(), ex);
        return new Result<>(ex.getCode(), ex.getMessage());
    }

    private static String getStackTrace(Throwable e) {
        StringBuilder sb = new StringBuilder();
        StackTraceElement[] stackArray = e.getStackTrace();
        for (int i = 0; i < stackArray.length; i++) {
            StackTraceElement element = stackArray[i];
            sb.append(element.toString() + " ");
        }
        return sb.toString();
    }
}
